package com.bainuo.doctor.common.image_support.filedownload;


import com.bainuo.doctor.common.model.FileDownLoadTask;


import com.blankj.utilcode.utils.LogUtils;
import com.orhanobut.hawk.Hawk;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class FileDownloader extends IFileDownload{


	private OkHttpClient mOkHttpClient = new OkHttpClient();

	/**
	 * 开始下载
	 * @param task
     */
	@Override
	public void startDownload(final FileDownLoadTask task) {

		//非空判断
		if (task == null
				|| task.getUrl() == null
				|| task.getTid() == null
				|| task.getSavePath() == null
				//|| task.getStatus() == FileDownLoadTask.TASK_STATUS.STATUS_DOWNLOADING
				|| task.getStatus() == FileDownLoadTask.TASK_STATUS.STATUS_DOWNLOAD_FINISH)  return;

		synchronized(this){

			//检查是否是新添加的
			FileDownLoadTask _task = _taskMap.get(task.getTid());
			if (_task == null){
				_taskMap.put(task.getTid(),task);
			}

			if (_downloadQueue.size() >= _downLoadTaskMaxCount && _downloadQueue.get(task.getTid()) == null){
				return;
			}

			//加入下载队列
			_downloadQueue.put(task.getTid(),task);
		}


		task.setStatus(FileDownLoadTask.TASK_STATUS.STATUS_DOWNLOADING);
		//开始下载
		if (_listener != null)
			_listener.onDownloadStart(task);


		if(!canDownload(task))
			return;

//		Request.Builder builder = new Request.Builder().url("http://down.tech.sina.com.cn/download/d_load.php?d_id=40975&down_id=5&ip=58.250.243.24");
//		Request request = new Request.Builder().url(task.getUrl()).build();

		Request.Builder builder = null;
		try {
			builder = new Request.Builder().url(task.getUrl());
		}catch (Exception e){
			if (_listener != null)
				_listener.onDownloadFailed(task);
			e.printStackTrace();
			return;
		}

		//确定下载的范围,添加此头,则服务器就可以跳过已经下载好的部分
		if (task.getDownloadedLength() != 0 && task.getFileSize() != 0) {
			builder.addHeader("RANGE", "bytes=" + task.getDownloadedLength() + "-" + task.getFileSize());
		}
		Request request	= builder.build();

		mOkHttpClient.newCall(request).enqueue(new Callback() {

			 @Override
			 public void onFailure(Call call, IOException e) {

				 //下载失败
				 task.setStatus(FileDownLoadTask.TASK_STATUS.STATUS_DOWNLOAD_FAILED);
				 if (_listener != null)
					 _listener.onDownloadFailed(task);

				 startNext(task);
			 }

			 @Override
			 public void onResponse(Call call, Response response) throws IOException {

				 InputStream is = null;
				 byte[] buf = new byte[2048];
				 int len = 0;
				 FileOutputStream fos = null;

				 //下载到临时文件
				 File file = new File(task.getTmpPath());
				 try {
					 is = response.body().byteStream();
					 int total = (int)response.body().contentLength();

					 LogUtils.e("tag","onResponse total---->  "+total);

					 //如果长度没有保存则 保存
					 if (total != 0 && task.getFileSize() == 0){
						 task.setFileSize(total);
						 Hawk.put(task.getTid(),total);
					 }

					 if (task.getFileSize() != 0){
						 total = task.getFileSize();
					 }


					 fos = new FileOutputStream(file,task.getDownloadedLength()!=0);
					 int sum = task.getDownloadedLength();

					 while ((len = is.read(buf)) != -1
							 && task.getStatus() == FileDownLoadTask.TASK_STATUS.STATUS_DOWNLOADING
							 )
					 {
						 fos.write(buf, 0, len);
						 sum += len;

						 if(total != 0) {
//							 int preProgress = task.getProgress();
							 task.setProgress(sum * 1.0f / total);
//							 if(preProgress != task.getProgress()){
								 if (_listener != null)
									 _listener.onDownloadProgress(task);
//							 }
						 }

						 task.setDownloadedLength(task.getDownloadedLength()+len);
					 }
					 fos.flush();


					 if(task.getStatus() == FileDownLoadTask.TASK_STATUS.STATUS_DOWNLOADING) {

						 file.renameTo(new File(task.getSavePath()));
						 task.setStatus(FileDownLoadTask.TASK_STATUS.STATUS_DOWNLOAD_FINISH);
						 if (_listener != null)
							 _listener.onDownloadSuccess(task);

					 }else if(task.getStatus() == FileDownLoadTask.TASK_STATUS.STATUS_DOWNLOAD_PAUSE){

					 }


					 startNext(task);
					 LogUtils.d("h_bl", "文件下载成功");
				 } catch (Exception e) {
					 LogUtils.d("h_bl", "文件下载失败");

//					 file.delete();
//					 task.setDownloadedLength(0);
//					 Hawk.delete(task.getTid());
					 onFailure(null,null);

				 } finally {
					 try {
						 if (is != null)
							 is.close();
					 } catch (IOException e) {
					 }
					 try {
						 if (fos != null)
							 fos.close();
					 } catch (IOException e) {
					 }
				 }
			 }
		});
	}

	/**
	 * 下载一条
	 * @param task
     */
	protected  void startNext(FileDownLoadTask task){
		synchronized (FileDownloader.this){
			_downloadQueue.remove(task.getTid());

			for (FileDownLoadTask _task : _taskMap.values()){
				if (_task.getStatus() == FileDownLoadTask.TASK_STATUS.STATUS_DOWNLOAD_PRE){
					startDownload(_task);
					break;
				}
			}
		}
	}


	/**
	 *  暂停任务
	 * @param tid
     */
	@Override
	public void pauseTask(String tid) {
		synchronized (this){
			FileDownLoadTask task = _taskMap.get(tid);
			if (task != null){
				task.setStatus(FileDownLoadTask.TASK_STATUS.STATUS_DOWNLOAD_PAUSE);
				if (_listener != null)
					_listener.onDownloadPause(task);
			}
		}
	}

	/**
	 * 获取任务进度
	 * @param tid
	 * @return
     */
	@Override
	public int getTaskProgress(String tid) {
		synchronized (this){
			FileDownLoadTask task = _taskMap.get(tid);
			if (task != null){
				return task.getProgress();
			}
		}
		return 0;
	}


	/**
	 * 获取任务状态
	 * @param tid
	 * @return
     */
	@Override
	public FileDownLoadTask.TASK_STATUS getTaskStatus(String tid) {
		synchronized (this){
			FileDownLoadTask task = _taskMap.get(tid);
			if (task != null){
				return task.getStatus();
			}
		}
		return FileDownLoadTask.TASK_STATUS.STATUS_DOWNLOAD_NO_EXIST;
	}

	@Override
	public FileDownLoadTask getTask(String tid) {
		synchronized (this){
			FileDownLoadTask task = _taskMap.get(tid);
			if (task != null){
				return task;
			}
		}
		return null;
	}

	@Override
	public void cancelTask(String aUrl) {

	}

	@Override
	public boolean canDownload(FileDownLoadTask task) {
		return true;
	}
}